﻿using System;
using System.Windows;
using Microsoft.Phone.Controls;
using System.IO.IsolatedStorage;
using System.Diagnostics;
using System.Windows.Controls;

namespace OpenThesaurus
{
    public partial class Options : PhoneApplicationPage
    {
        /// <summary>
        /// The key to set or read the user's choice regarding similar results from the openthesaurus.de-API from the IsolatedStorage.
        /// </summary>
        public const string OPTION_SIMILAR_RESULTS = "similarresults";

        /// <summary>
        /// The default behaviour is to show similar results.
        /// </summary>
        private const bool OPTION_SIMILAR_RESULTS_DEFAULT_VALUE = true;

        /// <summary>
        /// The key to set or read the user's choice regarding substring results from the openthesaurus.de-API from the IsolatedStorage.
        /// </summary>
        public const string OPTION_SUBSTRING_RESULTS = "substringresults";

        /// <summary>
        /// The default behaviour is to show substring results.
        /// </summary>
        private const bool OPTION_SUBSTRING_RESULTS_DEFAULT_VALUE = true;

        /// <summary>
        /// Constructor that initializes the current app instance.
        /// </summary>
        public Options()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Stores the user's choice.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbSimilarWords_Checked(object sender, System.Windows.RoutedEventArgs e)
        {
            insertOrUpdateStoredUserSettings(OPTION_SIMILAR_RESULTS);
        }

        /// <summary>
        /// Stores the user's choice.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbSubstrings_Checked(object sender, System.Windows.RoutedEventArgs e)
        {
            insertOrUpdateStoredUserSettings(OPTION_SUBSTRING_RESULTS);
        }

        /// <summary>
        /// Stores the user's choice.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbSimilarWords_Unchecked(object sender, System.Windows.RoutedEventArgs e)
        {
            insertOrUpdateStoredUserSettings(OPTION_SIMILAR_RESULTS);
        }

        /// <summary>
        /// Stores the user's choice.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbSubstrings_Unchecked(object sender, System.Windows.RoutedEventArgs e)
        {
            insertOrUpdateStoredUserSettings(OPTION_SUBSTRING_RESULTS);
        }

        /// <summary>
        /// Updates the status of the checkboxes for the respective options each time the page gets loaded.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContentPanel_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            initializeOptionsFromStorage();
        }

        /// <summary>
        /// The method required to initialize the API query string in Search.xaml accoring to the user's settings.
        /// </summary>
        public void initializeOptionsFromStorage()
        {
            // get the respective initialization values for the available options
            initializeOptionsFromStorage(OPTION_SIMILAR_RESULTS, OPTION_SIMILAR_RESULTS_DEFAULT_VALUE);
            initializeOptionsFromStorage(OPTION_SUBSTRING_RESULTS, OPTION_SUBSTRING_RESULTS_DEFAULT_VALUE);
        }

        /// <summary>
        /// Initializes the controls on the options page according to the persisted application settings.
        /// </summary>
        /// <param name="key">The key of the option to be initialized</param>
        /// <param name="defaultValue">The default value in case none is set</param>
        private void initializeOptionsFromStorage(string key, bool defaultValue)
        {
            #region Read stored value for the respective option
            if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
            {
                try
                {
                    // since the "as" operator (as string) doesn't allow non-nullable types an explizit conversion is necessary.
                    string storedValueTemp = IsolatedStorageSettings.ApplicationSettings[key].ToString();

                    Debug.WriteLine("Valid value \"" + storedValueTemp + "\" for key \"" + key + "\" found");
                    // convert value "True" or "False" to a valid bool for conversion
                    storedValueTemp = storedValueTemp.ToLower();

                    // Convert the string value to Boolean
                    bool storedValue = Boolean.Parse(storedValueTemp);

                    // identify the current option and set the stored values
                    switch (key)
                    {
                        case OPTION_SIMILAR_RESULTS:
                            // set the stored values
                            cbSimilarResults.IsChecked = storedValue;
                            break;

                        case OPTION_SUBSTRING_RESULTS:
                            // set the stored  values
                            cbSubstrings.IsChecked = storedValue;
                            break;
                    }
                }
                catch (Exception ex) // error while storing the user's setting
                {
                    Debug.WriteLine("Error while converting the stored boolean value from string to bool!");
                    Debug.WriteLine(ex.Message);

                    Debug.WriteLine("Fallback: Setting default settings.");
                    // The default behaviour is to enable all options
                    // identify the current option and set the default values
                    setDefaultValueAndUpdateUi(key, defaultValue);
                }
            }
            else // no stored settings found for the current key
            {
                try
                {
                    setDefaultValueAndUpdateUi(key, defaultValue);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Error while persisting the default settings!");
                    Debug.WriteLine(ex.Message);
                }

            }
            #endregion
        }

        /// <summary>
        /// Stores the default value for the respective key.
        /// </summary>
        /// <param name="key">the settings key</param>
        /// <param name="defaultValue">the default value for the given key</param>
        private void setDefaultValueAndUpdateUi(string key, bool defaultValue)
        {
            Debug.WriteLine("No existing settings found. Setting default value \"" + defaultValue + "\" for key \"" + key + "\"");
            IsolatedStorageSettings.ApplicationSettings[key] = defaultValue;

            // identify the current option and update the UI
            switch (key)
            {
                case OPTION_SIMILAR_RESULTS:
                    cbSimilarResults.IsChecked = defaultValue;
                    break;

                case OPTION_SUBSTRING_RESULTS:
                    cbSubstrings.IsChecked = defaultValue;
                    break;
            }
        }

        /// <summary>
        /// Updates the persisted user settings with the current UI control status (checked/not checked).
        /// </summary>
        private void insertOrUpdateStoredUserSettings(string key)
        {
            IsolatedStorageSettings settings;

            try
            {
                settings = IsolatedStorageSettings.ApplicationSettings;

                // identify the option to update and set the updated value
                switch (key)
                {
                    case OPTION_SIMILAR_RESULTS:
                        // check if the key already exists in the IsolatedStorage
                        if (!settings.Contains(OPTION_SIMILAR_RESULTS))
                        {
                            // create it if not
                            settings.Add(OPTION_SIMILAR_RESULTS, OPTION_SIMILAR_RESULTS_DEFAULT_VALUE);
                            Debug.WriteLine("Key \"" + OPTION_SIMILAR_RESULTS + "\" didn't exist. Inserted the default value \"" + OPTION_SIMILAR_RESULTS_DEFAULT_VALUE + "\"");
                        }
                        else
                        {
                            // update it if already available
                            settings[OPTION_SIMILAR_RESULTS] = cbSimilarResults.IsChecked;
                            Debug.WriteLine("Key \"" + OPTION_SIMILAR_RESULTS + "\" already exists. Updated it with value \"" + cbSimilarResults.IsChecked + "\"");
                        }
                        break;

                    case OPTION_SUBSTRING_RESULTS:
                        // check if the key already exists in the IsolatedStorage
                        if (!settings.Contains(OPTION_SUBSTRING_RESULTS))
                        {
                            settings.Add(OPTION_SUBSTRING_RESULTS, cbSubstrings.IsChecked);
                            Debug.WriteLine("Key \"" + OPTION_SUBSTRING_RESULTS + "\" didn't exist. Inserted it with value \"" + cbSubstrings.IsChecked + "\"");
                        }
                        else // create it if not
                        {
                            settings[OPTION_SUBSTRING_RESULTS] = cbSubstrings.IsChecked;
                            Debug.WriteLine("Key \"" + OPTION_SUBSTRING_RESULTS + "\" already exists. Updated it with value \"" + cbSubstrings.IsChecked + "\"");
                        }
                        break;
                    }

                // persist changes
                settings.Save();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error while persisting the user settings!");
                Debug.WriteLine(ex.Message);
            }
        }

        
    }
}